package com.atguigu.spzx.user.service.impl;

import cn.hutool.core.net.Ipv4Util;
import cn.hutool.core.util.IdUtil;
import com.atguigu.spzx.common.exception.SpzxException;
import com.atguigu.spzx.common.interceptor.SpzxUserInfoInterceptor;
import com.atguigu.spzx.model.dto.h5.UserRegistDto;
import com.atguigu.spzx.model.entity.h5.UserInfo;
import com.atguigu.spzx.model.vo.common.ResultCodeEnum;
import com.atguigu.spzx.user.mapper.UserInfoMapper;
import com.atguigu.spzx.user.service.UserInfoService;
import com.atguigu.spzx.util.IpUtil;
import jakarta.annotation.Resource;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.util.DigestUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service
public class UserInfoServiceImpl implements UserInfoService {
    @Resource
    UserInfoMapper userInfoMapper;
    @Resource
    StringRedisTemplate stringRedisTemplate; //必须和存验证码的模板类对象一样
    @Resource
    RedisTemplate redisTemplate;
    @Override
    public void register(UserRegistDto userRegistDto) {
        //1、参数校验: 所有参数都不能为空
        String username = userRegistDto.getUsername();
        String password = userRegistDto.getPassword();
        String code = userRegistDto.getCode();
        String nickName = userRegistDto.getNickName();
        if(StringUtils.isEmpty(username)||
                StringUtils.isEmpty(password)||
                StringUtils.isEmpty(code)||
                StringUtils.isEmpty(nickName)
        ){
            throw new SpzxException(ResultCodeEnum.PARAMS_ERROR , null);
        }
        //2、验证验证码：
        String cacheCode = stringRedisTemplate.opsForValue().get("user:sms:code:" + username);
        if(!code.equals(cacheCode)){
            //验证码错误：
            throw new SpzxException(ResultCodeEnum.CODE_ERROR ,null);
        }
        //3、重复注册校验： 手机号不能重复
        int count = userInfoMapper.countByUsername(username);
        if(count>0){
            throw new SpzxException(ResultCodeEnum.MOBILE_EXISTS_ERROR ,null);
        }
        //4、密码加密
        String encodePwd = DigestUtils.md5DigestAsHex(password.getBytes());
        //5、保存用户数据到数据库
        UserInfo userInfo = new UserInfo();
        userInfo.setUsername(username);
        userInfo.setPassword(encodePwd);
        userInfo.setNickName(nickName);
        String defaultAvatar = "https://img.alicdn.com/imgextra/i4/O1CN01zJMPkf1vvDtzGGQKW_!!6000000006234-2-tps-144-144.png";
        userInfo.setAvatar(defaultAvatar);
        userInfo.setSex(1);
        userInfo.setPhone(username);
        userInfo.setStatus(1);//状态 1正常

        userInfoMapper.save(userInfo);
        //6、删除redis缓存的验证码
        stringRedisTemplate.delete("user:sms:code:" + username);

    }

    @Override
    public String login(UserInfo userInfo) {
        String username = userInfo.getUsername();
        String password = userInfo.getPassword();
        Assert.hasLength(username , "账号不能为空");
        Assert.hasLength(password , "密码不能为空");

        //1、使用账号查询用户信息
        userInfo = userInfoMapper.findUserInfoByUsername(username);
        //账号查询失败
//        Assert.isTrue(userInfo==null , "账号不存在");
        if(userInfo==null){
            throw new SpzxException(ResultCodeEnum.USERNAME_NOT_EXISTS , null);
        }
        //2、使用查询到的用户密码 和 加密后的登录密码比较
        String encodePwd = DigestUtils.md5DigestAsHex(password.getBytes());
        if(!encodePwd.equals(userInfo.getPassword())){
            throw new SpzxException(ResultCodeEnum.PASSOWRD_ERROR , null);
        }
        //用户账号是否正常
        if(userInfo.getStatus()!=1){
            throw new SpzxException(ResultCodeEnum.ACCOUNT_ERROR , null);
        }
        //3、保存登录状态： 生成token  将用户信息映射保存到redis中
        String token = IdUtil.createSnowflake(1, 1).nextIdStr();
        userInfo.setPassword("*****");
        redisTemplate.opsForValue().set("user:login:"+token , userInfo , 6 , TimeUnit.DAYS);

        //4、更新登录日志()
        userInfo.setLastLoginTime(new Date());
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        userInfo.setLastLoginIp(IpUtil.getIpAddress(requestAttributes.getRequest()));

        userInfoMapper.updateLoginInfo(userInfo);
        return token;
    }

    @Override
    public Map<String, String> getCurrentUserInfo() {
        UserInfo userInfo = SpzxUserInfoInterceptor.THREAD_LOCAL.get();

        Map<String, String> map = new HashMap<>();
        map.put("avatar" , userInfo.getAvatar());
        map.put("nickName" , userInfo.getNickName());
        return map;
    }
}
